/* 
热点管理模块, 
检测压缩文件存放的路径中所有的文件是否长时间未访问, 
并做相应的压缩处理。
*/
#ifndef __MY_HOTSPOT__MANAGER__
#define __MY_HOTSPOT__MANAGER__
#include "DataManager.hpp"
#include "Config.hpp"
#include <time.h>
#include <unistd.h>

namespace cloud
{
class HotspotManager
{
private:
    cloud::DataManager* _dm;
    std::string _ulPath;      // 上传文件存放的路径(这里指的是文件夹)
    std::string _rarPath;     // 压缩文件存放的路径(这里指的是文件夹)
    std::time_t _hotTime;     // 热点时间
public:
    HotspotManager()
    {
        _dm = new DataManager();
        cloud::Config* cf = cloud::Config::getInstance();
        _ulPath = cf->getUlPath();
        _rarPath = cf->getRarPath();
        _hotTime = cf->getHotTime();
    }

    ~HotspotManager()
    {
        delete _dm;
    }

    // 提供主要功能: 检测是否是热点+非热点删除并压缩+更改配置文件信息
    bool runHotspotManager()
    {
        cloud::FileUtil ful(_ulPath);       // 打开ulPath, 如果不存在, 就创建该dir
        if(ful.exits() == false) {
            ful.createDir();
        }
        cloud::FileUtil frar(_rarPath);    // 打开rarPath, 如果没有该path, 就创建dir
        if(frar.exits() == false) {
            frar.createDir();
        } 

        for(;;) {
            std::vector<std::string> fArray;     // 用于保存扫描到的文件
            ful.scanDir(&fArray);
            
            for(const auto& path : fArray) {
                // f是等待检查文件的路径
                if(checkHot(path) == true) {
                    // 是热点文件, 不需要处理
                    continue;
                } else {
                    // 不是热点文件, 将其压缩后, 将压缩包放入rarPath中, 并删除该文件
                    cloud::FileUtil files(path);         // 打开该目录下的一个一个的文件
                    if(compressAndMov(path, files) == false)    return false;
                    if(removeFile(files) == false)              return false;
                    if(updateAndStorage(path) == false)         return false;
                }
                usleep(1000);
            }
            // break;
        }
    }
private:
    // 检测是否是热点文件, 是返回true
    bool checkHot(const std::string& path)
    {
        cloud::FileUtil fu(path);
        // 获取该文件的信息
        if(time(NULL) - fu.getLastATime() > _hotTime) {
            // 大于配置文件中的_hotTime, 不是热点文件
            // std::cout << "No\n";
            return false;
        }
        // std::cout << "Yes\n";
        return true;
    }

    // 将文件压缩到指定位置
    bool compressAndMov(const std::string& path, cloud::FileUtil& fu)
    {
        cloud::BackupInfo info;

        // 获取该文件的信息
        if(_dm->get1FromPath(path, &info) == false) {
            // 本地有该文件, 但是没有放到哈希表中, 需要将其加载后放到哈希表和备份文件中
            cloud::BackupInfo bi(path);
            _dm->insertInfo(bi);
            _dm->strorageBackup();
            if(fu.compresss(bi.rarFilePath) == false)    return false;
            return true;
        }

        // rarPath下没有该压缩文件就会自动创建
        if(fu.compresss(info.rarFilePath) == false)    return false;        
        return true;
    }

    // 删除文件
    bool removeFile(cloud::FileUtil& fu) 
    {
        if(fu.removeFile() == false)    return false;
        return true;
    }

    // 更新文件的信息, 并进行持久化操作
    bool updateAndStorage(const std::string& path)
    {
        cloud::BackupInfo info;
        // 获取该文件的信息
        if(_dm->get1FromPath(path, &info) == false)    return false;
        info.isPacked = true;
        _dm->updateInfo(info);
        if(_dm->strorageBackup() == false)             return false;
        return true;
    }
};
} 

#endif